from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Dict, Any, Optional
import logging
import uvicorn

from config import Config
from zhipuai_client import ZhipuAIClient
from recommendation_engine import RecommendationEngine
from nlp_analyzer import NLPAnalyzer
from learning_analyzer import LearningAnalyzer
from models import *
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from models import (
    User, Course, Student, Assignment, AssignmentSubmission, 
    Resource, Exam, ExamResult, Feedback, Teacher
)

# 配置日志
logging.basicConfig(
    level=getattr(logging, Config.LOG_LEVEL),
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(Config.LOG_FILE),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)

# 创建FastAPI应用
app = FastAPI(
    title="AI智能教学培训系统",
    description="基于智谱AI的个性化学习系统",
    version="1.0.0"
)

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 假设你有数据库连接配置
engine = create_engine(Config.SQLALCHEMY_DATABASE_URI)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# 初始化AI组件
zhipuai_client = ZhipuAIClient()
recommendation_engine = RecommendationEngine()
nlp_analyzer = NLPAnalyzer()
learning_analyzer = LearningAnalyzer()

# 请求模型
class ChatRequest(BaseModel):
    question: str
    role: Optional[str] = "student"
    context: Optional[str] = None
    subject: Optional[str] = "general"
    student: Optional[dict] = None
    course: Optional[dict] = None

class TextAnalysisRequest(BaseModel):
    text: str
    analysis_type: Optional[str] = "comprehensive"

class LearningAnalysisRequest(BaseModel):
    student_id: int
    learning_records: List[Dict[str, Any]]
    course_info: Optional[Dict[str, Any]] = None

class RecommendationRequest(BaseModel):
    user_id: int
    user_profile: Dict[str, Any]
    resources: List[Dict[str, Any]]
    algorithm: Optional[str] = "hybrid"
    limit: Optional[int] = 10

class AssignmentAnalysisRequest(BaseModel):
    content: str
    expected_topic: Optional[str] = None

# 响应模型
class ApiResponse(BaseModel):
    success: bool
    data: Optional[Dict[str, Any]] = None
    message: Optional[str] = None
    error: Optional[str] = None

@app.get("/")
async def root():
    """根路径"""
    return {"message": "AI智能教学培训系统API", "version": "1.0.0"}

@app.get("/health")
async def health_check():
    """健康检查"""
    return {"status": "healthy", "timestamp": "2024-01-01T00:00:00Z"}

@app.post("/api/ai/chat", response_model=ApiResponse)
async def chat_with_ai(request: ChatRequest, db: Session = Depends(get_db)):
    try:
        # 1. 解析问题类型（可用简单关键词匹配或NLU）
        question = request.question
        question_type = analyze_question_type(question)
        db_info = ""
        
        if question_type == "成绩查询":
            # 查询学生成绩
            student_id = request.student.get("student_id") if request.student else None
            # 如果request中没有学生ID，尝试从问题文本中提取
            if not student_id:
                student_id = extract_student_id_from_question(question)
            
            if student_id:
                # 查询学生的考试成绩和考试信息
                exam_results = db.query(ExamResult).filter_by(student_id=student_id).all()
                
                if exam_results:
                    score_info = []
                    total_score = 0
                    exam_count = 0
                    
                    for result in exam_results:
                        # 获取考试详细信息
                        exam = db.query(Exam).filter_by(exam_id=result.exam_id).first()
                        course = None
                        if exam:
                            course = db.query(Course).filter_by(course_id=exam.course_id).first()
                        
                        score = result.score or 0
                        total_score += score
                        exam_count += 1
                        
                        score_info.append({
                            "考试ID": result.exam_id,
                            "考试标题": exam.title if exam else f"考试{result.exam_id}",
                            "课程名称": course.name if course else "未知课程",
                            "成绩": score,
                            "反馈": result.feedback if result.feedback else "无",
                            "考试日期": exam.exam_date.strftime("%Y-%m-%d %H:%M") if exam and exam.exam_date else "未知"
                        })
                    
                    # 计算平均分
                    average_score = total_score / exam_count if exam_count > 0 else 0
                    
                    # 构建完整的成绩信息
                    db_info = {
                        "学生ID": student_id,
                        "考试总数": exam_count,
                        "平均分": round(average_score, 2),
                        "总分数": total_score,
                        "成绩详情": score_info
                    }
                    
                    db_info = f"学生考试成绩：{db_info}"
                else:
                    db_info = f"学生ID为{student_id}的学生暂无考试成绩"
            else:
                # 如果没有学生ID，查询所有考试成绩
                all_results = db.query(ExamResult).all()
                if all_results:
                    all_score_info = []
                    for result in all_results:
                        exam = db.query(Exam).filter_by(exam_id=result.exam_id).first()
                        course = None
                        if exam:
                            course = db.query(Course).filter_by(course_id=exam.course_id).first()
                        
                        all_score_info.append({
                            "学生ID": result.student_id,
                            "考试ID": result.exam_id,
                            "考试标题": exam.title if exam else f"考试{result.exam_id}",
                            "课程名称": course.name if course else "未知课程",
                            "成绩": result.score or 0,
                            "反馈": result.feedback if result.feedback else "无"
                        })
                    
                    db_info = f"所有考试成绩：{all_score_info}"
                else:
                    db_info = "暂无考试成绩信息"
        elif question_type == "课程查询":
            # 查询课程信息
            courses = db.query(Course).all()
            if courses:
                course_list = []
                total_courses = len(courses)
                
                for course in courses:
                    # 获取教师信息
                    teacher = db.query(Teacher).filter_by(teacher_id=course.teacher_id).first()
                    
                    # 获取课程相关的统计信息
                    assignment_count = db.query(Assignment).filter_by(course_id=course.course_id).count()
                    exam_count = db.query(Exam).filter_by(course_id=course.course_id).count()
                    resource_count = db.query(Resource).filter_by(course_id=course.course_id).count()
                    
                    course_info = {
                        "课程ID": course.course_id,
                        "课程名称": course.name,
                        "课程描述": course.description,
                        "授课教师": teacher.name if teacher else "未知教师",
                        "教师部门": teacher.department if teacher else "未知",
                        "创建时间": course.created_time.strftime("%Y-%m-%d %H:%M") if course.created_time else "无",
                        "作业数量": assignment_count,
                        "考试数量": exam_count,
                        "学习资源": resource_count
                    }
                    course_list.append(course_info)
                
                # 构建完整的课程信息
                course_summary = {
                    "课程总数": total_courses,
                    "课程列表": course_list
                }
                
                db_info = f"课程信息：{course_summary}"
            else:
                db_info = "暂无课程信息"
        elif question_type == "作业查询":
            # 查询作业信息
            student_id = request.student.get("student_id") if request.student else None
            # 如果request中没有学生ID，尝试从问题文本中提取
            if not student_id:
                student_id = extract_student_id_from_question(question)
            
            if student_id:
                # 查询学生的作业信息（包括提交情况）
                assignments = db.query(Assignment).all()
                submissions = db.query(AssignmentSubmission).filter_by(student_id=student_id).all()
                
                if assignments:
                    assignment_info = []
                    for assignment in assignments:
                        # 查找该学生是否已提交此作业
                        submission = next((s for s in submissions if s.assignment_id == assignment.assignment_id), None)
                        
                        assignment_info.append({
                            "作业ID": assignment.assignment_id,
                            "标题": assignment.title,
                            "描述": assignment.description,
                            "截止日期": assignment.due_date.strftime("%Y-%m-%d %H:%M") if assignment.due_date else "无",
                            "创建时间": assignment.created_time.strftime("%Y-%m-%d %H:%M") if assignment.created_time else "无",
                            "提交状态": "已提交" if submission else "未提交",
                            "提交时间": submission.submitted_time.strftime("%Y-%m-%d %H:%M") if submission and submission.submitted_time else "无",
                            "得分": submission.score if submission else "未评分",
                            "反馈": submission.feedback if submission else "无"
                        })
                    
                    db_info = f"学生作业信息：{assignment_info}"
                else:
                    db_info = "暂无作业信息"
            else:
                # 如果没有学生ID，查询所有作业
                assignments = db.query(Assignment).all()
                if assignments:
                    assignment_list = []
                    for assignment in assignments:
                        assignment_list.append({
                            "作业ID": assignment.assignment_id,
                            "标题": assignment.title,
                            "描述": assignment.description,
                            "截止日期": assignment.due_date.strftime("%Y-%m-%d %H:%M") if assignment.due_date else "无",
                            "创建时间": assignment.created_time.strftime("%Y-%m-%d %H:%M") if assignment.created_time else "无"
                        })
                    db_info = f"所有作业信息：{assignment_list}"
                else:
                    db_info = "暂无作业信息"
        
        elif question_type == "资源查询":
            # 查询学习资源
            resources = db.query(Resource).all()
            if resources:
                resource_list = []
                for resource in resources:
                    resource_list.append({
                        "资源ID": resource.resource_id,
                        "标题": resource.title,
                        "描述": resource.description,
                        "类型": resource.type,
                        "URL": resource.url,
                        "版本": resource.version,
                        "上传时间": resource.uploaded_time.strftime("%Y-%m-%d %H:%M") if resource.uploaded_time else "无"
                    })
                db_info = f"学习资源列表：{resource_list}"
            else:
                db_info = "暂无学习资源"
        
        elif question_type == "考试查询":
            # 查询考试信息
            student_id = request.student.get("student_id") if request.student else None
            if not student_id:
                student_id = extract_student_id_from_question(question)
            
            if student_id:
                # 查询学生的考试信息和成绩
                exams = db.query(Exam).all()
                exam_results = db.query(ExamResult).filter_by(student_id=student_id).all()
                
                if exams:
                    exam_info = []
                    for exam in exams:
                        # 查找该学生的考试成绩
                        result = next((r for r in exam_results if r.exam_id == exam.exam_id), None)
                        
                        exam_info.append({
                            "考试ID": exam.exam_id,
                            "标题": exam.title,
                            "描述": exam.description,
                            "考试日期": exam.exam_date.strftime("%Y-%m-%d %H:%M") if exam.exam_date else "无",
                            "创建时间": exam.created_time.strftime("%Y-%m-%d %H:%M") if exam.created_time else "无",
                            "成绩": result.score if result else "未参加",
                            "反馈": result.feedback if result else "无"
                        })
                    
                    db_info = f"学生考试信息：{exam_info}"
                else:
                    db_info = "暂无考试信息"
            else:
                # 如果没有学生ID，查询所有考试
                exams = db.query(Exam).all()
                if exams:
                    exam_list = []
                    for exam in exams:
                        exam_list.append({
                            "考试ID": exam.exam_id,
                            "标题": exam.title,
                            "描述": exam.description,
                            "考试日期": exam.exam_date.strftime("%Y-%m-%d %H:%M") if exam.exam_date else "无",
                            "创建时间": exam.created_time.strftime("%Y-%m-%d %H:%M") if exam.created_time else "无"
                        })
                    db_info = f"所有考试信息：{exam_list}"
                else:
                    db_info = "暂无考试信息"
        
        elif question_type == "学生信息查询":
            # 查询学生信息
            student_id = request.student.get("student_id") if request.student else None
            if not student_id:
                student_id = extract_student_id_from_question(question)
            
            if student_id:
                student = db.query(Student).filter_by(student_id=student_id).first()
                if student:
                    db_info = f"学生信息：{{'学生ID': {student.student_id}, '姓名': '{student.name}', '邮箱': '{student.email}', '专业': '{student.major}', '入学年份': {student.enrollment_year}}}"
                else:
                    db_info = f"未找到学生ID为{student_id}的学生信息"
            else:
                # 查询所有学生
                students = db.query(Student).all()
                if students:
                    student_list = []
                    for student in students:
                        student_list.append({
                            "学生ID": student.student_id,
                            "姓名": student.name,
                            "邮箱": student.email,
                            "专业": student.major,
                            "入学年份": student.enrollment_year
                        })
                    db_info = f"所有学生信息：{student_list}"
                else:
                    db_info = "暂无学生信息"
        elif question_type == "反馈查询":
            # 查询反馈信息
            feedbacks = db.query(Feedback).all()
            if feedbacks:
                feedback_list = []
                for feedback in feedbacks:
                    feedback_list.append({
                        "反馈ID": feedback.feedback_id,
                        "学生ID": feedback.student_id,
                        "课程ID": feedback.course_id,
                        "内容": feedback.content,
                        "创建时间": feedback.created_time.strftime("%Y-%m-%d %H:%M") if feedback.created_time else "无"
                    })
                db_info = f"反馈信息：{feedback_list}"
            else:
                db_info = "暂无反馈信息"
        
        elif question_type == "成绩推荐":
            # 根据学生成绩推荐学习资源
            student_id = request.student.get("student_id") if request.student else None
            
            # 如果request中没有学生ID，尝试从问题文本中提取
            if not student_id:
                student_id = extract_student_id_from_question(question)
            
            if student_id:
                recommendation_info = get_personalized_recommendations_by_score(db, student_id)
                db_info = recommendation_info
            else:
                db_info = "请提供学生ID以获取个性化学习资源推荐"
        
        # 构建上下文信息
        context_info = ""
        if request.context:
            context_info = f"用户上下文：{request.context}\n"
        
        # 构建完整的 prompt
        prompt = ""
        if db_info:
            prompt += f"数据库信息：{db_info}\n"
        if context_info:
            prompt += context_info
        prompt += f"用户问题：{question}"
        
        logger.info(f"构建的prompt: {prompt}")

        # 传递给大模型
        response = zhipuai_client.answer_question(
            question=prompt,
            context=request.context,
            subject=request.subject
        )
        return ApiResponse(
            success=True,
            data={
                "answer": response.get("answer", ""),
                "question": question,
                "question_type": question_type,
                "related_resources": response.get("related_resources", []),
                "confidence": response.get("confidence", 0.0),
                "usage": response.get("usage", {})
            }
        )
    except Exception as e:
        logger.error(f"聊天接口错误: {str(e)}")
        return ApiResponse(success=False, error=f"AI服务错误: {str(e)}")

def analyze_question_type(question: str) -> str:
    """
    NLU 问题类型解析
    根据问题内容智能识别查询类型
    """
    question_lower = question.lower()


    # 成绩推荐相关关键词（优先级更高）
    recommendation_keywords = ['推荐', '建议', '学习资源推荐', '个性化推荐', '根据成绩推荐', '推荐学习', '根据我的成绩推荐']
    if any(keyword in question_lower for keyword in recommendation_keywords):
        return "成绩推荐"

    # 成绩相关关键词
    score_keywords = ['成绩', '分数', '考试分数', '考试成绩', '得分', '分数', 'score', 'grade']
    if any(keyword in question_lower for keyword in score_keywords):
        return "成绩查询"
    
    # 资源相关关键词（优先级更高，避免被课程关键词误判）
    resource_keywords = ['资源', '资料', '文件', '视频', '文档', 'resource', 'material', '学习资源']
    if any(keyword in question_lower for keyword in resource_keywords):
        return "资源查询"
    
    # 课程相关关键词
    course_keywords = ['课程', '课', '教学', 'course', 'class', 'lesson']
    if any(keyword in question_lower for keyword in course_keywords):
        return "课程查询"
    
    # 作业相关关键词
    assignment_keywords = ['作业', '任务', 'assignment', 'homework', 'task']
    if any(keyword in question_lower for keyword in assignment_keywords):
        return "作业查询"
    
    # 考试相关关键词
    exam_keywords = ['考试', '测试', '测验', 'exam', 'test', 'quiz']
    if any(keyword in question_lower for keyword in exam_keywords):
        return "考试查询"
    
    # 学生信息相关关键词
    student_keywords = ['学生', '同学', 'student', 'pupil']
    if any(keyword in question_lower for keyword in student_keywords):
        return "学生信息查询"
    
    # 学习进度相关关键词
    progress_keywords = ['进度', '学习进度', '完成情况', 'progress', 'completion']
    if any(keyword in question_lower for keyword in progress_keywords):
        return "学习进度查询"
    
    # 资源相关关键词
    resource_keywords = ['资源', '资料', '文件', '视频', '文档', 'resource', 'material']
    if any(keyword in question_lower for keyword in resource_keywords):
        return "资源查询"
    
    # 反馈相关关键词
    feedback_keywords = ['反馈', '建议', '意见', 'feedback', 'suggestion']
    if any(keyword in question_lower for keyword in feedback_keywords):
        return "反馈查询"
    
    # 默认返回通用查询
    return "通用查询"

@app.post("/api/ai/analyze-text", response_model=ApiResponse)
async def analyze_text(request: TextAnalysisRequest):
    """
    文本分析接口
    
    Args:
        request: 文本分析请求
        
    Returns:
        分析结果
    """
    try:
        logger.info(f"收到文本分析请求: {request.analysis_type}")
        
        # 调用NLP分析器
        analysis_result = nlp_analyzer.analyze_text(
            text=request.text,
            analysis_type=request.analysis_type
        )
        
        return ApiResponse(
            success=True,
            data=analysis_result
        )
        
    except Exception as e:
        logger.error(f"文本分析错误: {str(e)}")
        return ApiResponse(
            success=False,
            error=f"文本分析错误: {str(e)}"
        )

@app.post("/api/ai/analyze-assignment", response_model=ApiResponse)
async def analyze_assignment(request: AssignmentAnalysisRequest):
    """
    作业分析接口
    
    Args:
        request: 作业分析请求
        
    Returns:
        作业分析结果
    """
    try:
        logger.info("收到作业分析请求")
        
        # 调用NLP分析器分析作业
        analysis_result = nlp_analyzer.analyze_assignment(
            content=request.content,
            expected_topic=request.expected_topic
        )
        
        return ApiResponse(
            success=True,
            data=analysis_result
        )
        
    except Exception as e:
        logger.error(f"作业分析错误: {str(e)}")
        return ApiResponse(
            success=False,
            error=f"作业分析错误: {str(e)}"
        )

@app.post("/api/ai/analyze-learning", response_model=ApiResponse)
async def analyze_learning(request: LearningAnalysisRequest):
    """
    学习分析接口
    
    Args:
        request: 学习分析请求
        
    Returns:
        学习分析结果
    """
    try:
        logger.info(f"收到学习分析请求: 学生ID {request.student_id}")
        
        # 调用学习分析器
        analysis_result = learning_analyzer.analyze_learning_progress(
            student_id=request.student_id,
            learning_records=request.learning_records,
            course_info=request.course_info
        )
        
        return ApiResponse(
            success=True,
            data=analysis_result
        )
        
    except Exception as e:
        logger.error(f"学习分析错误: {str(e)}")
        return ApiResponse(
            success=False,
            error=f"学习分析错误: {str(e)}"
        )

@app.post("/api/ai/recommend", response_model=ApiResponse)
async def get_recommendations(request: RecommendationRequest):
    """
    个性化推荐接口
    
    Args:
        request: 推荐请求
        
    Returns:
        推荐结果
    """
    try:
        logger.info(f"收到推荐请求: 用户ID {request.user_id}, 算法 {request.algorithm}")
        
        # 构建用户-物品矩阵
        learning_records = []
        for resource in request.resources:
            # 模拟学习记录（实际应用中应该从数据库获取）
            learning_records.append({
                'user_id': request.user_id,
                'resource_id': resource.get('resource_id'),
                'study_time': 30.0,  # 模拟学习时间
                'completion_rate': 80.0,  # 模拟完成率
                'interaction_count': 5  # 模拟交互次数
            })
        
        # 构建用户-物品矩阵
        recommendation_engine.build_user_item_matrix(learning_records)
        
        # 获取推荐
        recommendations = recommendation_engine.get_personalized_recommendations(
            user_id=request.user_id,
            user_profile=request.user_profile,
            resources=request.resources,
            algorithm=request.algorithm,
            n_recommendations=request.limit
        )
        
        return ApiResponse(
            success=True,
            data=recommendations
        )
        
    except Exception as e:
        logger.error(f"推荐错误: {str(e)}")
        return ApiResponse(
            success=False,
            error=f"推荐错误: {str(e)}"
        )

@app.post("/api/ai/batch-analyze", response_model=ApiResponse)
async def batch_analyze_assignments(assignments: List[Dict[str, Any]]):
    """
    批量作业分析接口
    
    Args:
        assignments: 作业列表
        
    Returns:
        批量分析结果
    """
    try:
        logger.info(f"收到批量分析请求: {len(assignments)} 个作业")
        
        # 调用智谱AI批量分析
        analysis_results = zhipuai_client.batch_analyze_assignments(assignments)
        
        return ApiResponse(
            success=True,
            data={
                "total_assignments": len(assignments),
                "analysis_results": analysis_results
            }
        )
        
    except Exception as e:
        logger.error(f"批量分析错误: {str(e)}")
        return ApiResponse(
            success=False,
            error=f"批量分析错误: {str(e)}"
        )

@app.post("/api/ai/generate-recommendations", response_model=ApiResponse)
async def generate_ai_recommendations(student_profile: Dict[str, Any], 
                                    learning_history: List[Dict[str, Any]]):
    """
    生成AI学习推荐
    
    Args:
        student_profile: 学生档案
        learning_history: 学习历史
        
    Returns:
        AI生成的推荐
    """
    try:
        logger.info("收到AI推荐生成请求")
        
        # 调用智谱AI生成推荐
        recommendations = zhipuai_client.generate_learning_recommendations(
            student_profile=student_profile,
            learning_history=learning_history
        )
        
        return ApiResponse(
            success=True,
            data=recommendations
        )
        
    except Exception as e:
        logger.error(f"AI推荐生成错误: {str(e)}")
        return ApiResponse(
            success=False,
            error=f"AI推荐生成错误: {str(e)}"
        )

@app.get("/api/ai/models")
async def get_available_models():
    """获取可用的AI模型信息"""
    return {
        "zhipuai_model": Config.ZHIPUAI_MODEL,
        "nlp_model": Config.TEXT_ANALYSIS_MODEL,
        "recommendation_algorithms": [
            "collaborative_filtering",
            "content_based",
            "hybrid",
            "matrix_factorization"
        ]
    }

@app.get("/api/ai/config")
async def get_ai_config():
    """获取AI配置信息"""
    return {
        "min_similarity_threshold": Config.MIN_SIMILARITY_THRESHOLD,
        "max_recommendations": Config.MAX_RECOMMENDATIONS,
        "sentiment_threshold": Config.SENTIMENT_THRESHOLD,
        "learning_progress_weight": Config.LEARNING_PROGRESS_WEIGHT,
        "performance_weight": Config.PERFORMANCE_WEIGHT,
        "interest_weight": Config.INTEREST_WEIGHT
    }

# 错误处理
@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
    logger.error(f"全局异常: {str(exc)}")
    return ApiResponse(
        success=False,
        error=f"服务器内部错误: {str(exc)}"
    )

def get_personalized_recommendations_by_score(db: Session, student_id: int) -> str:
    """
    根据学生成绩推荐个性化学习资源
    
    Args:
        db: 数据库会话
        student_id: 学生ID
        
    Returns:
        推荐信息字符串
    """
    try:
        # 1. 查询学生成绩
        exam_results = db.query(ExamResult).filter_by(student_id=student_id).all()
        
        if not exam_results:
            return "该学生暂无考试成绩，无法进行个性化推荐"
        
        # 2. 分析成绩情况
        score_analysis = analyze_student_scores(exam_results, db)
        
        # 3. 查询所有可用资源
        all_resources = db.query(Resource).all()
        
        # 4. 根据成绩分析推荐资源
        recommended_resources = recommend_resources_by_score(score_analysis, all_resources)
        
        # 5. 构建推荐信息
        recommendation_info = {
            "学生ID": student_id,
            "成绩分析": score_analysis,
            "推荐资源": recommended_resources,
            "推荐理由": generate_recommendation_reason(score_analysis)
        }
        
        return f"个性化学习资源推荐：{recommendation_info}"
        
    except Exception as e:
        logger.error(f"获取个性化推荐失败: {str(e)}")
        return f"获取个性化推荐失败: {str(e)}"

def analyze_student_scores(exam_results: List[ExamResult], db: Session) -> dict:
    """
    分析学生成绩情况
    
    Args:
        exam_results: 考试成绩列表
        db: 数据库会话
        
    Returns:
        成绩分析结果
    """
    analysis = {
        "总考试数": len(exam_results),
        "平均分": 0.0,
        "最高分": 0.0,
        "最低分": 100.0,
        "成绩分布": {},
        "薄弱科目": [],
        "优势科目": [],
        "各科成绩": []
    }
    
    if not exam_results:
        return analysis
    
    total_score = 0
    scores = []
    
    for result in exam_results:
        score = result.score or 0
        scores.append(score)
        total_score += score
        
        # 获取考试信息
        exam = db.query(Exam).filter_by(exam_id=result.exam_id).first()
        if exam:
            course = db.query(Course).filter_by(course_id=exam.course_id).first()
            course_name = course.name if course else f"课程{exam.course_id}"
            
            analysis["各科成绩"].append({
                "课程": course_name,
                "考试": exam.title,
                "分数": score,
                "反馈": result.feedback
            })
    
    # 计算统计信息
    analysis["平均分"] = total_score / len(exam_results)
    analysis["最高分"] = max(scores)
    analysis["最低分"] = min(scores)
    
    # 分析成绩分布
    for score in scores:
        if score >= 90:
            analysis["成绩分布"]["优秀(90-100)"] = analysis["成绩分布"].get("优秀(90-100)", 0) + 1
        elif score >= 80:
            analysis["成绩分布"]["良好(80-89)"] = analysis["成绩分布"].get("良好(80-89)", 0) + 1
        elif score >= 70:
            analysis["成绩分布"]["中等(70-79)"] = analysis["成绩分布"].get("中等(70-79)", 0) + 1
        elif score >= 60:
            analysis["成绩分布"]["及格(60-69)"] = analysis["成绩分布"].get("及格(60-69)", 0) + 1
        else:
            analysis["成绩分布"]["不及格(<60)"] = analysis["成绩分布"].get("不及格(<60)", 0) + 1
    
    # 识别薄弱和优势科目
    for subject_score in analysis["各科成绩"]:
        if subject_score["分数"] < 70:
            analysis["薄弱科目"].append(subject_score["课程"])
        elif subject_score["分数"] >= 85:
            analysis["优势科目"].append(subject_score["课程"])
    
    return analysis

def recommend_resources_by_score(score_analysis: dict, all_resources: List[Resource]) -> List[dict]:
    """
    根据成绩分析推荐学习资源
    
    Args:
        score_analysis: 成绩分析结果
        all_resources: 所有可用资源
        
    Returns:
        推荐资源列表
    """
    recommended_resources = []
    
    # 根据薄弱科目推荐基础资源
    for weak_subject in score_analysis.get("薄弱科目", []):
        for resource in all_resources:
            # 匹配薄弱科目的基础资源
            if (weak_subject.lower() in resource.title.lower() or 
                weak_subject.lower() in resource.description.lower()):
                recommended_resources.append({
                    "资源ID": resource.resource_id,
                    "标题": resource.title,
                    "类型": resource.type,
                    "描述": resource.description,
                    "推荐理由": f"针对薄弱科目'{weak_subject}'的基础学习资源",
                    "优先级": "高"
                })
    
    # 根据平均分推荐进阶资源
    avg_score = score_analysis.get("平均分", 0)
    if avg_score >= 80:
        # 成绩优秀，推荐进阶资源
        for resource in all_resources:
            if "进阶" in resource.title or "高级" in resource.title or "深入" in resource.description:
                recommended_resources.append({
                    "资源ID": resource.resource_id,
                    "标题": resource.title,
                    "类型": resource.type,
                    "描述": resource.description,
                    "推荐理由": "基于优秀成绩推荐的进阶学习资源",
                    "优先级": "中"
                })
    elif avg_score < 70:
        # 成绩较差，推荐基础资源
        for resource in all_resources:
            if "基础" in resource.title or "入门" in resource.title or "基础" in resource.description:
                recommended_resources.append({
                    "资源ID": resource.resource_id,
                    "标题": resource.title,
                    "类型": resource.type,
                    "描述": resource.description,
                    "推荐理由": "基于较低成绩推荐的基础学习资源",
                    "优先级": "高"
                })
    
    # 去重并限制推荐数量
    unique_resources = []
    seen_ids = set()
    for resource in recommended_resources:
        if resource["资源ID"] not in seen_ids:
            unique_resources.append(resource)
            seen_ids.add(resource["资源ID"])
    
    return unique_resources[:10]  # 最多推荐10个资源

def generate_recommendation_reason(score_analysis: dict) -> str:
    """
    生成推荐理由
    
    Args:
        score_analysis: 成绩分析结果
        
    Returns:
        推荐理由
    """
    avg_score = score_analysis.get("平均分", 0)
    weak_subjects = score_analysis.get("薄弱科目", [])
    strong_subjects = score_analysis.get("优势科目", [])
    
    reasons = []
    
    if avg_score >= 85:
        reasons.append("你的成绩非常优秀，建议学习进阶内容以进一步提升")
    elif avg_score >= 75:
        reasons.append("你的成绩良好，可以适当挑战一些进阶内容")
    elif avg_score >= 65:
        reasons.append("你的成绩中等，建议巩固基础知识并适当提升")
    else:
        reasons.append("你的成绩需要提升，建议重点学习基础内容")
    
    if weak_subjects:
        reasons.append(f"在{', '.join(weak_subjects)}等科目上需要加强")
    
    if strong_subjects:
        reasons.append(f"在{', '.join(strong_subjects)}等科目上表现优秀，可以继续深入")
    
    return "；".join(reasons)

def extract_student_id_from_question(question: str) -> Optional[int]:
    """
    从问题文本中提取学生ID
    
    Args:
        question: 用户问题
        
    Returns:
        学生ID，如果没找到返回None
    """
    import re
    
    # 匹配模式：学生id为X、学生ID为X、id为X、ID为X等
    patterns = [
        r'学生id为(\d+)',
        r'学生ID为(\d+)',
        r'id为(\d+)',
        r'ID为(\d+)',
        r'我的学生id为(\d+)',
        r'我的学生ID为(\d+)',
        r'我的id为(\d+)',
        r'我的ID为(\d+)',
        r'学生(\d+)',
        r'学号(\d+)'
    ]
    
    for pattern in patterns:
        match = re.search(pattern, question, re.IGNORECASE)
        if match:
            try:
                return int(match.group(1))
            except ValueError:
                continue
    
    return None

if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
        log_level=Config.LOG_LEVEL.lower()
    )